#pragma once

#include "InteractionUse.h"

#include "Gate.h"
#include "Interaction.h"
#include "Property.h"
#include "ValueSpecification.h"

namespace uml {

InteractionUse::InteractionUse(const QString& umlType)
    : NamedElement(umlType) {}

void InteractionUse::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    NamedElement::fromJson(json, errorList);
    InteractionFragment::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(actualGates_, "actualGates", json, errorList);
    JsonSerializable::fromJsonArray(arguments_, "arguments", json, errorList);
    refersTo_ = JsonSerializable::create<Interaction>(json.value("refersTo"), errorList);

    returnValue_ = JsonSerializable::create<ValueSpecification>(json.value("returnValue"), errorList);

    returnValueRecipient_ = JsonSerializable::create<Property>(json.value("returnValueRecipient"), errorList);

}

void InteractionUse::toJson(QJsonObject& json) {
    NamedElement::toJson(json);
    InteractionFragment::toJson(json);
    JsonSerializable::toJsonArray(actualGates_, "actualGates", json);
    JsonSerializable::toJsonArray(arguments_, "arguments", json);
    if (refersTo_) {
        QJsonObject refersTo_json;
        refersTo_->toJson(refersTo_json);
        json.insert("refersTo", refersTo_json);
    }
    if (returnValue_) {
        QJsonObject returnValue_json;
        returnValue_->toJson(returnValue_json);
        json.insert("returnValue", returnValue_json);
    }
    if (returnValueRecipient_) {
        QJsonObject returnValueRecipient_json;
        returnValueRecipient_->toJson(returnValueRecipient_json);
        json.insert("returnValueRecipient", returnValueRecipient_json);
    }
}

/// <summary>
/// actualGates getter
/// The actual gates of the InteractionUse.
/// </summary>
vector<shared_ptr<Gate>>& InteractionUse::actualGates() {
    return actualGates_;
}

/// <summary>
/// arguments getter
/// The actual arguments of the Interaction.
/// </summary>
vector<shared_ptr<ValueSpecification>>& InteractionUse::arguments() {
    return arguments_;
}

/// <summary>
/// refersTo getter
/// Refers to the Interaction that defines its meaning.
/// </summary>
shared_ptr<Interaction> InteractionUse::refersTo() const {
    return refersTo_;
}

/// <summary>
/// refersTo setter
/// Refers to the Interaction that defines its meaning.
/// </summary>
void InteractionUse::setRefersTo(shared_ptr<Interaction> value) {
    refersTo_ = value;
}

/// <summary>
/// returnValue getter
/// The value of the executed Interaction.
/// </summary>
shared_ptr<ValueSpecification> InteractionUse::returnValue() const {
    return returnValue_;
}

/// <summary>
/// returnValue setter
/// The value of the executed Interaction.
/// </summary>
void InteractionUse::setReturnValue(shared_ptr<ValueSpecification> value) {
    returnValue_ = value;
}

/// <summary>
/// returnValueRecipient getter
/// The recipient of the return value.
/// </summary>
shared_ptr<Property> InteractionUse::returnValueRecipient() const {
    return returnValueRecipient_;
}

/// <summary>
/// returnValueRecipient setter
/// The recipient of the return value.
/// </summary>
void InteractionUse::setReturnValueRecipient(shared_ptr<Property> value) {
    returnValueRecipient_ = value;
}

} // namespace uml
